﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IdCard
{
    public class IDCardInfo
    {
        public string Name { get; set; }        // 姓名
        public string Gender { get; set; }       // 性别
        public string Ethnicity { get; set; }    // 民族
        public DateTime BirthDate { get; set; }  // 出生日期
        public string Address { get; set; }      // 住址
        public string IDNumber { get; set; }     // 公民身份号码
        public string IssuingAuthority { get; set; } // 签发机关
        public DateTime ValidFrom { get; set; }  // 有效期限起始
        public DateTime ValidTo { get; set; }    // 有效期限截止
        public byte[] PhotoData { get; set; }    // 照片二进制数据

        // 常量定义
        const int HEADER_SIZE = 14;     // 协议头长度
        const int TEXT_DATA_SIZE = 316; // 文字信息区固定长度
        public IDCardInfo ParseIDCardData(byte[] rawData)
        {
            

            // 创建编码对象（Unicode小端序）
            Encoding unicode = Encoding.Unicode;

            IDCardInfo info = new IDCardInfo();

            // 1. 解析文字信息区
            int textStart = HEADER_SIZE;

            // 姓名 (15个汉字，30字节)
            info.Name = CleanString(unicode.GetString(rawData, textStart, 30));

            // 性别 (1个汉字，2字节)
            info.Gender = unicode.GetString(rawData, textStart + 30, 2) == "1" ? "男" : "女";

            // 民族 (2个汉字，4字节)
            info.Ethnicity = CleanString(unicode.GetString(rawData, textStart + 32, 4));

            // 出生日期 (8字节数字，16字节存储)
            string birthDateStr = CleanString(unicode.GetString(rawData, textStart + 36, 16));
            info.BirthDate = ParseDate(birthDateStr);

            // 住址 (35个汉字，70字节)
            info.Address = CleanString(unicode.GetString(rawData, textStart + 52, 70));

            // 身份证号 (18字节数字，36字节存储)
            info.IDNumber = CleanString(unicode.GetString(rawData, textStart + 122, 36));

            // 签发机关 (15个汉字，30字节)
            info.IssuingAuthority = CleanString(unicode.GetString(rawData, textStart + 158, 30));

            // 有效期限 (16字节数字，32字节存储)
            string validPeriod = CleanString(unicode.GetString(rawData, textStart + 188, 32));
            if (validPeriod.Length >= 16)
            {
                info.ValidFrom = ParseDate(validPeriod.Substring(0, 8));
                info.ValidTo = ParseDate(validPeriod.Substring(8, 8));
            }

            // 2. 动态定位照片数据
            int photoStart = FindPhotoStartPosition(rawData);
            if (photoStart > 0 && photoStart < rawData.Length - 4)
            {
                // 照片长度字段（4字节小端序）
                int photoLength = BitConverter.ToInt32(rawData, photoStart);

                // 照片数据起始位置 = 照片长度字段位置 + 4
                int dataStart = photoStart + 4;

                if (dataStart + photoLength <= rawData.Length)
                {
                    info.PhotoData = new byte[photoLength];
                    Buffer.BlockCopy(rawData, dataStart, info.PhotoData, 0, photoLength);
                }
                else
                {
                    // 数据长度不足，尝试读取剩余所有数据
                    photoLength = rawData.Length - dataStart;
                    info.PhotoData = new byte[photoLength];
                    Buffer.BlockCopy(rawData, dataStart, info.PhotoData, 0, photoLength);
                }
            }
            else
            {
                //info.PhotoData = Array.Empty<byte>();
            }

            return info;
        }

        // 辅助方法：查找照片起始位置
        private int FindPhotoStartPosition(byte[] data)
        {
            // 照片数据通常以0xFF 0xD8（JPEG起始标记）开头
            // 在文字信息区之后搜索此标记
            const int TEXT_END = HEADER_SIZE + TEXT_DATA_SIZE;

            // 从文字信息区结束位置开始搜索
            for (int i = TEXT_END; i < data.Length - 1; i++)
            {
                // 查找可能的照片长度字段（小端序，通常小于100KB）
                if (i < data.Length - 4)
                {
                    int potentialLength = BitConverter.ToInt32(data, i);
                    if (potentialLength > 1024 && potentialLength < 1024 * 100) // 合理范围
                    {
                        // 验证后续数据是否为JPEG
                        if (i + 4 < data.Length - 1 &&
                            data[i + 4] == 0xFF &&
                            data[i + 5] == 0xD8)
                        {
                            return i;
                        }
                    }
                }

                // 直接查找JPEG起始标记
                if (data[i] == 0xFF && data[i + 1] == 0xD8)
                {
                    // 回溯4字节查找长度字段
                    if (i >= 4)
                    {
                        int lengthPos = i - 4;
                        int potentialLength = BitConverter.ToInt32(data, lengthPos);
                        if (potentialLength > 1024 && potentialLength < 1024 * 100)
                        {
                            return lengthPos;
                        }
                    }
                    return i; // 即使没有长度字段也返回起始位置
                }
            }
            return -1; // 未找到
        }

        // 辅助方法：清理字符串
        private string CleanString(string input)
        {
            return input
                .Replace("\0", "")   // 移除空字符
                .Replace(" ", "")    // 移除空格
                .Trim();             // 移除首尾空白
        }

        // 辅助方法：解析日期
        private DateTime ParseDate(string dateStr)
        {
            if (dateStr.Length == 8 && dateStr.All(char.IsDigit))
            {
                return DateTime.ParseExact(dateStr, "yyyyMMdd", CultureInfo.InvariantCulture);
            }
            return DateTime.MinValue; // 返回默认值表示无效日期
        }
    }


}
